﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Collections;
using RAP.Framework.Libary.Utils;
using System.Text.RegularExpressions;

namespace RAP.Framework.Libary.DataSource
{
  public static class ServiceUtils
  {
    public static class CacheTypes
    {
      /// <summary>
      /// 不需要缓存
      /// </summary>
      public const string None = "NONE";

      /// <summary>
      /// 自动根据CallerMemberName和NameSpace构造cacheKey来缓存
      /// </summary>
      public const string Auto = "AUTO_CACHE_KEY";
    }

    #region 常量

    /// <summary>
    ///  as 
    /// </summary>
    public const string AS_SYNTAX = " as ";

    /// <summary>
    ///  on 
    /// </summary>
    public const string ON_SYNTAX = " on ";

    /// <summary>
    ///  into 
    /// </summary>
    public const string INTO_SYNTAX = " into ";

    /// <summary>
    ///  join 
    /// </summary>
    public const string JOIN_SYNTAX = " join ";

    /// <summary>
    /// 缓存键的字段名称
    /// </summary>
    public const string CACHE_KEY_FIELD = "cacheKey";

    /// <summary>
    /// 通过模板配置获取的缓存数据节点名称：cache-result
    /// </summary>
    public const string CACHE_RESULT_FIELD = "cache-result";

    /// <summary>
    /// 数据库配置节点字段：DataConfig
    /// </summary>
    public static string DATA_CONFIG_FIELD = "DataConfig";

    /// <summary>
    /// 数据源配置项的key：DataSources
    /// </summary>
    public static string DATA_SOURCES_FIELD = "DataSources";

    /// <summary>
    /// 数据库查询时指定数据源的Id：DataSource
    /// </summary>
    public static string DATA_SOURCE_FIELD = "DataSource";

    /// <summary>
    /// 默认的数据库Id：DefaultDataSourceId
    /// </summary>
    public static string DEFAULT_DATA_SOURCE_ID_FIELD = "DefaultDataSourceId";

    /// <summary>
    /// 数据库服务类型集合字段：Providers
    /// </summary>
    public const string DATA_PROVIDERS_FIELD = "Providers";

    /// <summary>
    /// 数据库服务类型Id：Provider
    /// </summary>
    public const string DATA_PROVIDER_FIELD = "Provider";

    /// <summary>
    /// 数据库连接字符串字段：connectionString
    /// </summary>
    public const string CONNECTION_STRING_FIELD = "ConnectionString";

    /// <summary>
    /// sql
    /// </summary>
    public const string SQL_FIELD = "sql";

    /// <summary>
    /// service
    /// </summary>
    public const string SERVICE_FIELD = "service";

    /// <summary>
    /// method
    /// </summary>
    public const string METHOD_FIELD = "method";

    /// <summary>
    /// run
    /// </summary>
    public const string RUN_SERICE = "run";

    /// <summary>
    /// alias
    /// </summary>
    public const string RESULT_ALIAS = "alias";

    /// <summary>
    /// paramResult
    /// </summary>
    public const string RESULT_PARAM = "paramResult";

    /// <summary>
    /// reduceHandler
    /// </summary>
    public const string RESULT_REDUCE_HANDLER = "reduceHandler";

    /// <summary>
    /// data
    /// </summary>
    public const string RESULT_DATA_FIELD = "data";

    /// <summary>
    /// form
    /// </summary>
    public const string RESULT_FORM_FIELD = "form";

    /// <summary>
    /// type
    /// </summary>
    public const string RESULT_TYPE_FIELD = "type";

    /// <summary>
    /// map
    /// </summary>
    public const string RESULT_TYPE_MAP = "map";

    /// <summary>
    /// list
    /// </summary>
    public const string RESULT_TYPE_LIST = "list";

    /// <summary>
    /// errorMessage
    /// </summary>
    public const string ERROR_MESSAGE_FIELD = "errorMessage";

    /// <summary>
    /// stackTrace
    /// </summary>
    public const string ERROR_STACK_TRACE = "stackTrace";

    /// <summary>
    /// errorCode
    /// </summary>
    public const string ERROR_FIELD = "error";

    /// <summary>
    /// errorCode
    /// </summary>
    public const string ERROR_CODE_FIELD = "errorCode";

    /// <summary>
    /// result
    /// </summary>
    public const string RESULT_FIELD = "result";

    /// <summary>
    /// serviceType
    /// </summary>
    public const string SERVICE_TYPE = "serviceType";

    /// <summary>
    /// resultJSON
    /// </summary>
    public const string RESULT_JSON = "resultJSON";

    /// <summary>
    /// param
    /// </summary>
    public const string PARAM_FIELD = "param";

    /// <summary>
    /// context
    /// </summary>
    public const string CONTEXT_FIELD = "context";

    /// <summary>
    /// tpl
    /// </summary>
    public const string TEMPLATE_FIELD = "tpl";

    /// <summary>
    /// cacheProxyKey
    /// </summary>
    public const string CACHE_PROXY_KEY_FIELD = "cacheProxyKey";

    /// <summary>
    /// 查询的结果数据类型：dataType（map、table）
    /// </summary>
    public const string RESULT_DATA_TYPE_FIELD = "dataType";

    /// <summary>
    /// 数据源标识无效！
    /// </summary>
    public const string INVALID_DATA_PROVIDER_IDENTITY = "数据源类型不能为空或【{0}】类型未定义！";
    
    /// <summary>
		/// 按指定的数据模型解析查询结果
		/// </summary>
		public const string RESULT_DATA_TYPE_MODEL = "model";

    /// <summary>
    /// 结果集别名索引
    /// </summary>
    public const string RESULT_ALIAS_INDEX = "ResultAliasIndex";
    #endregion

    #region tsql常量
    /// <summary>
    /// trans
    /// </summary>
    public const string TSQL_NEED_TRANSACTION = "trans";//是否开启事务

    /// <summary>
    /// query
    /// </summary>
    public const string TSQL_COMMAND_QUERY = "query";

    /// <summary>
    /// update
    /// </summary>
    public const string TSQL_COMMAND_UPDATE = "update";

    /// <summary>
    /// delete
    /// </summary>
    public const string TSQL_COMMAND_DELETE = "delete";

    /// <summary>
    /// get
    /// </summary>
    public const string TSQL_COMMAND_GET = "get";

    /// <summary>
    /// save
    /// </summary>
    public const string TSQL_COMMAND_SAVE = "save";

    /// <summary>
    /// sql
    /// </summary>
    public const string TSQL_FIELD = "sql";

    /// <summary>
    /// debug
    /// </summary>
    public const string TSQL_DEBUG = "debug";

    /// <summary>
    /// allowDebug
    /// </summary>
    public const string TSQL_ALLOW_DEBUG = "allowDebug";

    /// <summary>
    /// 未知错误！
    /// </summary>
    public const string UNKNOWN_ERROR = "未知错误！";

    /// <summary>
    /// 未知错误的编码
    /// </summary>
    public const int UNKNOWN_ERROR_CODE = int.MinValue;

    /// <summary>
    /// 查询语句无效！
    /// </summary>
    public const string TSQL_INVALID_QUERY = "查询语句无效！";

    /// <summary>
    /// 查询语句无效的错误编码
    /// </summary>
    public const int TSQL_INVALID_QUERY_CODE = -99;

    /// <summary>
    /// 无效的查询参数！
    /// </summary>
    public const string TSQL_INVALID_PARAM = "无效的查询参数！";

    /// <summary>
    /// 无效的查询参数的错误编码
    /// </summary>
    public const int TSQL_INVALID_PARAM_CODE = -3;

    /// <summary>
    /// SQL
    /// </summary>
    public const string SERVICE_SQL_IDENTITY = "SQL";

    /// <summary>
    /// debug
    /// </summary>
    public const string DEBUG_FIELD = "debug";

    /// <summary>
    /// allowDebug
    /// </summary>
    public const string ALLOW_DEBUG_FIELD = "allowDebug";

    /// <summary>
    /// 是否允许空SQL语句，如果允许，则查询服务不报错，否则会报错：查询语句不能为空
    /// </summary>
    public const string ALLOW_EMPTY_SQL_FIELD = "allowEmptySql";

    /// <summary>
    /// 查询的进度字段：StepProgress
    /// </summary>
    public const string STEP_PROGRESS_FIELD = "StepProgress";

    /// <summary>
    /// 同步查询步骤字段：Steps
    /// </summary>
    public const string STEPS_FIELD = "Steps";

    /// <summary>
    /// 同步查询步骤字段：steps
    /// </summary>
    public const string LOWER_STEPS_FIELD = "steps";

    /// <summary>
    /// 同步查询的步骤数量
    /// </summary>
    public const string STEP_COUNT_FIELD = "StepCount";

    /// <summary>
    /// 当前同步查询的索引
    /// </summary>
    public const string CURRENT_STEP_INDEX_FIELD = "StepIndex";

    /// <summary>
    /// 当前同步查询的Id
    /// </summary>
    public const string CURRENT_STEP_ID_FIELD = "StepId";

    /// <summary>
    /// 查询结果集限定字段：ResultMaps
    /// </summary>
    public const string RESULTS_FIELD = "ResultMaps";

    /// <summary>
    /// 查询结果集限定字段：resultMaps
    /// </summary>
    public const string LOWER_RESULTS_FIELD = "resultMaps";

    /// <summary>
    /// 当前已查询到的记录数
    /// </summary>
    public const string CURRENT_DATA_COUNT_FIELD = "dataCount";

    /// <summary>
    /// 操作耗时(ms)：duration 
    /// </summary>
    public const string DURATION_FIELD = "duration";

    /// <summary>
    /// 操作开始的时间：startTime
    /// </summary>
    public const string START_TIME_FIELD = "startTime";

    /// <summary>
    /// 操作结束的时间：endTime
    /// </summary>
    public const string END_TIME_FIELD = "endTime";

    #endregion tsql常量

    /// <summary>
    /// 
    /// </summary>
    /// <param name="resultValue"></param>
    /// <param name="type"></param>
    /// <returns></returns>
    public static object GetResultData(object resultValue, string type = RESULT_TYPE_LIST)
    {
      IDictionary resultData = null;
      if (resultValue is string)
      {
        resultData = resultValue.ToString().ToDictionary();
      }
      else
      {
        resultData = resultValue as IDictionary;
      }
      if (resultData.ToInt32(ERROR_CODE_FIELD, 0) == 0)
      {
        resultValue = resultData[RESULT_DATA_FIELD];
      }
      else
      {
        resultValue = resultData;
      }
      if (type == RESULT_TYPE_MAP)
      {
        if (resultValue is IList)
        {
          IList list = (resultValue as IList);
          if (list.Count > 0)
          {
            resultValue = list[0];
          }
          else
          {
            resultValue = null;
          }
        }
      }
      return resultValue;
    }

    /// <summary>
    /// 处理查询参数
    /// </summary>
    /// <param name="queryParams"></param>
    public static object ProcessQueryParams(object queryParams, Action<IDictionary> processAction)
    {
      if (queryParams is IDictionary)
      {
        processAction(queryParams as IDictionary);
      }
      else if (queryParams is IList)
      {
        foreach (object param in queryParams as IList)
        {
          ProcessQueryParams(param, processAction);
        }
      }
      return queryParams;
    }

    /// <summary>
    /// 处理每一个Tpl
    /// </summary>
    /// <param name="queryParams"></param>
    /// <param name="processAction"></param>
    public static void ProcessQueryTemplates(object queryParams, Action<IDictionary, string> processAction)
    {
      Action<IDictionary, object> process = null;
      process = (param, tpl) =>
      {
        if (tpl is string)
        {
          string[] tpls = tpl.ToString().Split(',');
          foreach (string tplId in tpls)
          {
            processAction(param, tplId);
          }
        }
        else if (tpl is IDictionary)
        {
          process(param, (tpl as IDictionary).ToObject<object>(TEMPLATE_FIELD, null));
        }
        else if (tpl is IList)
        {
          foreach (object tplObj in (tpl as IList))
          {
            process(param, tplObj);
          }
        }
      };

      ProcessQueryParams(queryParams, (param) =>
     {
       process(param, param.ToObject<object>(TEMPLATE_FIELD, null));
     });
    }

    /// <summary>
    /// 创建一个异常结果对象
    /// </summary>
    /// <param name="errorCode">错误编码</param>
    /// <param name="errorMessage">错误信息</param>
    /// <returns></returns>
    public static IDictionary CreateErrorResult(string errorMessage, int errorCode = -9999)
    {
      return new Hashtable
            {
                {
                    ERROR_CODE_FIELD, errorCode
                },
                {
                    ERROR_MESSAGE_FIELD, errorMessage
                }
            };
    }

    /// <summary>
    /// 创建一个结果对象
    /// </summary>
    /// <param name="value"></param>
    /// <returns></returns>
    public static IDictionary CreateResult(object value)
    {
      return new Hashtable
            {
                {
                    RESULT_FIELD, value
                }
            };
    }
  }
}